/*
 * Copyright (C) 2016 huanghaibin_dev <huanghaibin_dev@163.com>
 * WebSite https://github.com/MiracleTimes-Dev
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.elvis.library;


import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

/**
 * 日历布局
 * 鸿蒙与安卓触摸机制不同，未实现滑动切换周视图与月视图
 */
@SuppressWarnings("unused")
@Deprecated
public class CalendarLayout extends DirectionalLayout implements Component.EstimateSizeListener, Component.BindStateChangedListener, Component.TouchEventListener {

    /**
     * 多点触控支持
     */
    private int mActivePointerId;

    private static final int ACTIVE_POINTER = 1;

    private static final int INVALID_POINTER = -1;

    /**
     * 周月视图
     */
    private static final int CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW = 0;


    /**
     * 仅周视图
     */
    private static final int CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW = 1;

    /**
     * 仅月视图
     */
    private static final int CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW = 2;

    /**
     * 默认展开
     */
    private static final int STATUS_EXPAND = 0;

    /**
     * 默认收缩
     */
    private static final int STATUS_SHRINK = 1;

    /**
     * 默认状态
     */
    private int mDefaultStatus;

    private boolean isWeekView;

    /**
     * 星期栏
     */
    WeekBar mWeekBar;

    /**
     * 自定义ViewPager，月视图
     */
    MonthViewPager mMonthView;

    /**
     * 日历
     */
    CalendarView mCalendarView;

    /**
     * 自定义的周视图
     */
    WeekViewPager mWeekPager;

    /**
     * 年视图
     */
    YearViewPager mYearView;

    /**
     * ContentView
     */
    ComponentContainer mContentView;

    /**
     * 默认手势
     */
    private static final int GESTURE_MODE_DEFAULT = 0;

//       /**
    //     * 仅日历有效
    //     */
//    private static final int GESTURE_MODE_ONLY_CALENDAR = 1;

    /**
     * 禁用手势
     */
    private static final int GESTURE_MODE_DISABLED = 2;

    /**
     * 手势模式
     */
    private int mGestureMode;


    private int mCalendarShowMode;

    private int mContentViewTranslateY; //ContentView  可滑动的最大距离距离 , 固定
    private int mViewPagerTranslateY = 0;// ViewPager可以平移的距离，不代表mMonthView的平移距离

    private float downY;
    private float mLastY;
    private float mLastX;
    private boolean isAnimating = false;

    /**
     * 内容布局id
     */
    private int mContentViewId;

    /**
     * 手速判断
     */
    private VelocityDetector mVelocityTracker;
    private int mMaximumVelocity;

    private int mItemHeight;

    private CalendarViewDelegate mDelegate;

    public CalendarLayout(Context context, AttrSet attrSet) {
        super(context, attrSet);
        setOrientation(VERTICAL);
        if (attrSet.getAttr("calendar_content_view_id").isPresent()) {
            mContentViewId = attrSet.getAttr("calendar_content_view_id").get().getIntegerValue();
        } else {
            mContentViewId = 0;
        }
        if (attrSet.getAttr("default_status").isPresent()) {
            mDefaultStatus = attrSet.getAttr("default_status").get().getIntegerValue();
        } else {
            mDefaultStatus = STATUS_EXPAND;
        }
        if (attrSet.getAttr("calendar_show_mode").isPresent()) {
            mCalendarShowMode = attrSet.getAttr("calendar_show_mode").get().getIntegerValue();
        } else {
            mCalendarShowMode = CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW;
        }
        if (attrSet.getAttr("gesture_mode").isPresent()) {
            mGestureMode = attrSet.getAttr("gesture_mode").get().getIntegerValue();
        } else {
            mGestureMode = GESTURE_MODE_DEFAULT;
        }
        mVelocityTracker = VelocityDetector.obtainInstance();

        int mTouchSlop = 8;
        mMaximumVelocity = 8000;

        setEstimateSizeListener(this);
        setBindStateChangedListener(this);
        setTouchEventListener(this);
    }

    /**
     * 初始化
     *
     * @param delegate delegate
     */
    final void setup(CalendarViewDelegate delegate) {
        this.mDelegate = delegate;
        mItemHeight = mDelegate.getCalendarItemHeight();
        initCalendarPosition(delegate.mSelectedCalendar.isAvailable() ?
                delegate.mSelectedCalendar :
                delegate.createCurrentDate());
        updateContentViewTranslateY();
    }

    /**
     * 初始化当前时间的位置
     *
     * @param cur 当前日期时间
     */
    private void initCalendarPosition(Calendar cur) {
        int diff = CalendarUtil.getMonthViewStartDiff(cur, mDelegate.getWeekStart());
        int size = diff + cur.getDay() - 1;
        updateSelectPosition(size);
    }

    /**
     * 当前第几项被选中，更新平移量
     *
     * @param selectPosition 月视图被点击的position
     */
    final void updateSelectPosition(int selectPosition) {
        int line = (selectPosition + 7) / 7;
        mViewPagerTranslateY = (line - 1) * mItemHeight;
    }

    /**
     * 设置选中的周，更新位置
     *
     * @param week week
     */
    final void updateSelectWeek(int week) {
        mViewPagerTranslateY = (week - 1) * mItemHeight;
    }


    /**
     * 更新内容ContentView可平移的最大距离
     */
    void updateContentViewTranslateY() {
        Calendar calendar = mDelegate.mIndexCalendar;
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ALL_MONTH) {
            mContentViewTranslateY = 5 * mItemHeight;
        } else {
            mContentViewTranslateY = CalendarUtil.getMonthViewHeight(calendar.getYear(),
                    calendar.getMonth(), mItemHeight, mDelegate.getWeekStart())
                    - mItemHeight;
        }
        //已经显示周视图，则需要动态平移contentView的高度
        if (mWeekPager.getVisibility() == VISIBLE) {
            if (mContentView == null)
                return;
            mContentView.setTranslationY(-mContentViewTranslateY);
        }
    }

    /**
     * 更新日历项高度
     */
    final void updateCalendarItemHeight() {
        mItemHeight = mDelegate.getCalendarItemHeight();
        if (mContentView == null)
            return;
        Calendar calendar = mDelegate.mIndexCalendar;
        updateSelectWeek(CalendarUtil.getWeekFromDayInMonth(calendar, mDelegate.getWeekStart()));
        if (mDelegate.getMonthViewShowMode() == CalendarViewDelegate.MODE_ALL_MONTH) {
            mContentViewTranslateY = 5 * mItemHeight;
        } else {
            mContentViewTranslateY = CalendarUtil.getMonthViewHeight(calendar.getYear(), calendar.getMonth(),
                    mItemHeight, mDelegate.getWeekStart()) - mItemHeight;
        }
        translationViewPager();
        if (mWeekPager.getVisibility() == VISIBLE) {
            mContentView.setTranslationY(-mContentViewTranslateY);
        }
    }

    /**
     * 隐藏日历
     */
    public void hideCalendarView() {
        if (mCalendarView == null) {
            return;
        }
        mCalendarView.setVisibility(HIDE);
        if (!isExpand()) {
            expand(0);
        }
        postLayout();
    }

    /**
     * 显示日历
     */
    public void showCalendarView() {

        mCalendarView.setVisibility(VISIBLE);
        postLayout();
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        if (mGestureMode == GESTURE_MODE_DISABLED ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW) {//禁用手势，或者只显示某种视图
            return false;
        }
        if (mDelegate == null) {
            return false;
        }
        if (mDelegate.isShowYearSelectedLayout) {
            return false;
        }

        if (mContentView == null || mCalendarView == null || mCalendarView.getVisibility() == HIDE) {
            return false;
        }

        int action = event.getAction();
        MmiPoint point = event.getPointerPosition(event.getIndex());

        float y = point.getY();
        mVelocityTracker.addEvent(event);
        switch (action) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                int index = event.getIndex();
                mActivePointerId = event.getPointerId(index);
                mLastY = downY = y;
                return true;
            case TouchEvent.OTHER_POINT_DOWN: {
                final int indexx = event.getIndex();
                mActivePointerId = event.getPointerId(indexx);
                if (mActivePointerId == 0) {
                    //核心代码：就是让下面的 dy = y- mLastY == 0，避免抖动
                    mLastY = event.getPointerPosition(mActivePointerId).getY();
                }
                break;
            }
            case TouchEvent.POINT_MOVE:
                getPointerIndex(event, mActivePointerId);
                if (mActivePointerId == INVALID_POINTER) {
                    //如果切换了手指，那把mLastY换到最新手指的y坐标即可，核心就是让下面的 dy== 0，避免抖动
                    mLastY = y;
                    mActivePointerId = ACTIVE_POINTER;
                }
                float dy = y - mLastY;

                //向上滑动，并且contentView平移到最大距离，显示周视图
                if (dy < 0 && mContentView.getTranslationY() == -mContentViewTranslateY) {
                    mLastY = y;
//                    event.setAction(MotionEvent.ACTION_DOWN);
//                    dispatchTouchEvent(event);
                    mWeekPager.setVisibility(VISIBLE);
                    mMonthView.setVisibility(INVISIBLE);
                    if (!isWeekView && mDelegate.mViewChangeListener != null) {
                        mDelegate.mViewChangeListener.onViewChange(false);
                    }
                    isWeekView = true;
                    return true;
                }
                hideWeek(false);

                //向下滑动，并且contentView已经完全平移到底部
                if (dy > 0 && mContentView.getTranslationY() + dy >= 0) {
                    mContentView.setTranslationY(0);
                    translationViewPager();
                    mLastY = y;
                    return false;
                }

                //向上滑动，并且contentView已经平移到最大距离，则contentView平移到最大的距离
                if (dy < 0 && mContentView.getTranslationY() + dy <= -mContentViewTranslateY) {
                    mContentView.setTranslationY(-mContentViewTranslateY);
                    translationViewPager();
                    mLastY = y;
                    return false;
                }
                //否则按比例平移
                mContentView.setTranslationY(mContentView.getTranslationY() + dy);
                translationViewPager();
                mLastY = y;
                break;
            case TouchEvent.CANCEL:
            case TouchEvent.OTHER_POINT_UP:
                int pointerIndex = getPointerIndex(event, mActivePointerId);
                if (mActivePointerId == INVALID_POINTER)
                    break;
                mLastY = event.getPointerPosition(pointerIndex).getY();
                break;
            case TouchEvent.PRIMARY_POINT_UP:

                final VelocityDetector velocityTracker = mVelocityTracker;
                velocityTracker.calculateCurrentVelocity(1000, mMaximumVelocity, mMaximumVelocity);
                float mYVelocity = velocityTracker.getVerticalVelocity();
                if (mContentView.getTranslationY() == 0
                        || mContentView.getTranslationY() == mContentViewTranslateY) {
                    expand();
                    break;
                }
                if (Math.abs(mYVelocity) >= 800) {
                    if (mYVelocity < 0) {
                        shrink();
                    } else {
                        expand();
                    }
                    return false;
                }
                if (y - downY > 0) {
                    expand();
                } else {
                    shrink();
                }
                break;
        }
        return true;
    }

//    @Override
//    public boolean dispatchTouchEvent(MotionEvent ev) {
//        if (isAnimating) {
//            return super.dispatchTouchEvent(ev);
//        }
//        if (mGestureMode == GESTURE_MODE_DISABLED) {
//            return super.dispatchTouchEvent(ev);
//        }
//        if (mYearView == null ||
//                mCalendarView == null || mCalendarView.getVisibility() == GONE ||
//                mContentView == null ||
//                mContentView.getVisibility() != VISIBLE) {
//            return super.dispatchTouchEvent(ev);
//        }
//
//        if (mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
//                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW) {
//            return super.dispatchTouchEvent(ev);
//        }
//
//        if (mYearView.getVisibility() == VISIBLE || mDelegate.isShowYearSelectedLayout) {
//            return super.dispatchTouchEvent(ev);
//        }
//        final int action = ev.getAction();
//        float y = ev.getY();
//        if (action == MotionEvent.ACTION_MOVE) {
//            float dy = y - mLastY;
//            /*
//             * 如果向下滚动，有 2 种情况处理 且y在ViewPager下方
//             * 1、RecyclerView 或者其它滚动的View，当mContentView滚动到顶部时，拦截事件
//             * 2、非滚动控件，直接拦截事件
//             */
//            if (dy > 0 && mContentView.getTranslationY() == -mContentViewTranslateY) {
//                if (isScrollTop()) {
//                    requestDisallowInterceptTouchEvent(false);//父View向子View拦截分发事件
//                    return super.dispatchTouchEvent(ev);
//                }
//            }
//        }
//        return super.dispatchTouchEvent(ev);
//    }

    //    @Override
//    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        if (isAnimating) {
//            return true;
//        }
//        if (mGestureMode == GESTURE_MODE_DISABLED) {
//            return false;
//        }
//        if (mYearView == null ||
//                mCalendarView == null || mCalendarView.getVisibility() == GONE ||
//                mContentView == null ||
//                mContentView.getVisibility() != VISIBLE) {
//            return super.onInterceptTouchEvent(ev);
//        }
//
//        if (mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
//                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW) {
//            return false;
//        }
//
//        if (mYearView.getVisibility() == VISIBLE || mDelegate.isShowYearSelectedLayout) {
//            return super.onInterceptTouchEvent(ev);
//        }
//        final int action = ev.getAction();
//        float y = ev.getY();
//        float x = ev.getX();
//        switch (action) {
//            case MotionEvent.ACTION_DOWN:
//                int index = ev.getActionIndex();
//                mActivePointerId = ev.getPointerId(index);
//                mLastY = downY = y;
//                mLastX = x;
//                break;
//            case MotionEvent.ACTION_MOVE:
//                float dy = y - mLastY;
//                float dx = x - mLastX;
//                 /*
//                   如果向上滚动，且ViewPager已经收缩，不拦截事件
//                 */
//                if (dy < 0 && mContentView.getTranslationY() == -mContentViewTranslateY) {
//                    return false;
//                }
//                /*
//                 * 如果向下滚动，有 2 种情况处理 且y在ViewPager下方
//                 * 1、RecyclerView 或者其它滚动的View，当mContentView滚动到顶部时，拦截事件
//                 * 2、非滚动控件，直接拦截事件
//                 */
//                if (dy > 0 && mContentView.getTranslationY() == -mContentViewTranslateY
//                        && y >= mDelegate.getCalendarItemHeight() + mDelegate.getWeekBarHeight()) {
//                    if (!isScrollTop()) {
//                        return false;
//                    }
//                }
//
//                if (dy > 0 && mContentView.getTranslationY() == 0 && y >= CalendarUtil.dipToPx(getContext(), 98)) {
//                    return false;
//                }
//
//                if (Math.abs(dy) > Math.abs(dx)) { //纵向滑动距离大于横向滑动距离,拦截滑动事件
//                    if ((dy > 0 && mContentView.getTranslationY() <= 0)
//                            || (dy < 0 && mContentView.getTranslationY() >= -mContentViewTranslateY)) {
//                        mLastY = y;
//                        return true;
//                    }
//                }
//                break;
//        }
//        return super.onInterceptTouchEvent(ev);
//    }
//
//
    private int getPointerIndex(TouchEvent ev, int id) {
        int activePointerIndex = ev.getIndex();
//        int activePointerIndex = ev.getPointerPosition(id);
        if (activePointerIndex == -1) {
            mActivePointerId = INVALID_POINTER;
        }
        return activePointerIndex;
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        if (mContentView == null || mCalendarView == null) {
            return false;
        }
        int year = mDelegate.mIndexCalendar.getYear();
        int month = mDelegate.mIndexCalendar.getMonth();
        int weekBarHeight = CalendarUtil.vpToPx(getContext(), 1)
                + mDelegate.getWeekBarHeight();

        int monthHeight = CalendarUtil.getMonthViewHeight(year, month,
                mDelegate.getCalendarItemHeight(),
                mDelegate.getWeekStart(),
                mDelegate.getMonthViewShowMode())
                + weekBarHeight;

        int height = EstimateSpec.getSize(heightMeasureSpec);
        if (mDelegate.isFullScreenCalendar()) {
            setEstimatedSize(widthMeasureSpec, heightMeasureSpec);
            int heightSpec = EstimateSpec.getSizeWithMode(height - weekBarHeight - mDelegate.getCalendarItemHeight(),
                    EstimateSpec.PRECISE);
            mContentView.estimateSize(widthMeasureSpec, height);
            mContentView.arrange(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(), mContentView.getBottom());
            return true;
        }

        if (monthHeight >= height && mMonthView.getHeight() > 0) {
            height = monthHeight;
            heightMeasureSpec = EstimateSpec.getSizeWithMode(monthHeight +
                    weekBarHeight +
                    mDelegate.getWeekBarHeight(), EstimateSpec.PRECISE);
        } else if (monthHeight < height && mMonthView.getHeight() > 0) {
            heightMeasureSpec = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE);
        }

        int h;
        if (mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW ||
                mCalendarView.getVisibility() == HIDE) {
            h = height - (mCalendarView.getVisibility() == HIDE ? 0 : mCalendarView.getHeight());
        } else if (mGestureMode == GESTURE_MODE_DISABLED && !isAnimating) {
            if (isExpand()) {
                h = height - monthHeight;
            } else {
                h = height - weekBarHeight - mItemHeight;
            }
        } else {
            h = height - weekBarHeight - mItemHeight;
        }
        setEstimatedSize(widthMeasureSpec, heightMeasureSpec);

        int heightSpec = EstimateSpec.getSizeWithMode(h,
                EstimateSpec.PRECISE);
        mContentView.estimateSize(widthMeasureSpec, heightSpec);
        mContentView.arrange(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(), mContentView.getBottom());

        return true;
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
        mMonthView = (MonthViewPager) findComponentById(ResourceTable.Id_vp_month);
        mWeekPager = (WeekViewPager) findComponentById(ResourceTable.Id_vp_week);
        if (getChildCount() > 0) {
            mCalendarView = (CalendarView) getComponentAt(0);
        }
        mContentView = (ComponentContainer) findComponentById(mContentViewId);
        mYearView = (YearViewPager) findComponentById(ResourceTable.Id_selectLayout);
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {

    }


    /**
     * 平移ViewPager月视图
     */
    private void translationViewPager() {
        float percent = mContentView.getTranslationY() * 1.0f / mContentViewTranslateY;
        mMonthView.setTranslationY(mViewPagerTranslateY * percent);
    }


    public void setModeBothMonthWeekView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW;
        postLayout();
    }

    public void setModeOnlyWeekView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW;
        postLayout();
    }

    public void setModeOnlyMonthView() {
        mCalendarShowMode = CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW;
        postLayout();
    }


//    @Nullable
//    @Override
//    protected Parcelable onSaveInstanceState() {
//        Bundle bundle = new Bundle();
//        Parcelable parcelable = super.onSaveInstanceState();
//        bundle.putParcelable("super", parcelable);
//        bundle.putBoolean("isExpand", isExpand());
//        return bundle;
//    }
//
//    @Override
//    protected void onRestoreInstanceState(Parcelable state) {
//        Bundle bundle = (Bundle) state;
//        Parcelable superData = bundle.getParcelable("super");
//        boolean isExpand = bundle.getBoolean("isExpand");
//        if (isExpand) {
//            post(new Runnable() {
//                @Override
//                public void run() {
//                    expand(0);
//                }
//            });
//        } else {
//            post(new Runnable() {
//                @Override
//                public void run() {
//                    shrink(0);
//                }
//            });
//
//        }
//        super.onRestoreInstanceState(superData);
//    }

    /**
     * 是否展开了
     *
     * @return isExpand
     */
    public final boolean isExpand() {
        return mMonthView.getVisibility() == VISIBLE;
    }


    public boolean expand() {
        return expand(240);
    }


    /**
     * 展开
     *
     * @param duration 时长
     * @return 展开是否成功
     */
    public boolean expand(int duration) {
        if (isAnimating ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW ||
                mContentView == null)
            return false;
        if (mMonthView.getVisibility() != VISIBLE) {
            mWeekPager.setVisibility(HIDE);
            onShowMonthView();
            isWeekView = false;
            mMonthView.setVisibility(VISIBLE);
        }
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(duration);

        float start = mContentView.getTranslationY();
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                float curr = start + v * -start;
                mContentView.setTranslationY(curr);
                float percent = curr / mContentViewTranslateY;
                mMonthView.setTranslationY(mViewPagerTranslateY * percent);
                isAnimating = true;
            }
        });
        animatorValue.setStateChangedListener(new StateChangedListenerAdapter() {
            @Override
            public void onEnd(Animator animator) {
                isAnimating = false;
                if (mGestureMode == GESTURE_MODE_DISABLED) {
                    postLayout();
                }
                hideWeek(true);
                if (mDelegate.mViewChangeListener != null && isWeekView) {
                    mDelegate.mViewChangeListener.onViewChange(true);
                }
                isWeekView = false;
            }
        });
        animatorValue.start();
        return true;
    }

    public boolean shrink() {
        return shrink(240);
    }

    /**
     * 收缩
     *
     * @param duration 时长
     * @return 成功或者失败
     */
    public boolean shrink(int duration) {
        if (mGestureMode == GESTURE_MODE_DISABLED) {
            postLayout();
        }
        if (isAnimating || mContentView == null) {
            return false;
        }
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(duration);

        float start = mContentView.getTranslationY();
        float total = -mContentViewTranslateY - start;
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                float curr = start + v * total;
                mContentView.setTranslationY(curr);
                float percent = curr / mContentViewTranslateY;
                mMonthView.setTranslationY(mViewPagerTranslateY * percent);
                isAnimating = true;
            }
        });
        animatorValue.setStateChangedListener(new StateChangedListenerAdapter() {
            @Override
            public void onEnd(Animator animator) {
                isAnimating = false;
                showWeek();
                isWeekView = true;
            }
        });
        animatorValue.start();
        return true;
    }

    /**
     * 初始化状态
     */
    final void initStatus() {

        if ((mDefaultStatus == STATUS_SHRINK ||
                mCalendarShowMode == CALENDAR_SHOW_MODE_ONLY_WEEK_VIEW) &&
                mCalendarShowMode != CALENDAR_SHOW_MODE_ONLY_MONTH_VIEW) {
            if (mContentView == null) {
                mWeekPager.setVisibility(VISIBLE);
                mMonthView.setVisibility(HIDE);
                return;
            }
            post(new Runnable() {
                @Override
                public void run() {
                    AnimatorValue animatorValue = new AnimatorValue();
                    animatorValue.setDuration(0);

                    float start = mContentView.getTranslationY();
                    float total = -mContentViewTranslateY - start;
                    animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                        @Override
                        public void onUpdate(AnimatorValue animatorValue, float v) {
                            float curr = start + v * total;
                            mContentView.setTranslationY(curr);
                            float percent = curr / mContentViewTranslateY;
                            mMonthView.setTranslationY(mViewPagerTranslateY * percent);
                            isAnimating = true;
                        }
                    });
                    animatorValue.setStateChangedListener(new StateChangedListenerAdapter() {
                        @Override
                        public void onEnd(Animator animator) {
                            isAnimating = false;
                            isWeekView = true;
                            showWeek();
                            if (mDelegate == null || mDelegate.mViewChangeListener == null) {
                                return;
                            }
                            mDelegate.mViewChangeListener.onViewChange(false);
                        }
                    });
                    animatorValue.start();
                }
            });
        } else {
            if (mDelegate.mViewChangeListener == null) {
                return;
            }
            post(new Runnable() {
                @Override
                public void run() {
                    mDelegate.mViewChangeListener.onViewChange(true);
                }
            });
        }
    }

    private void post(Runnable runnable) {
        getContext().getUITaskDispatcher().asyncDispatch(runnable);
    }

    /**
     * 隐藏周视图
     */
    private void hideWeek(boolean isNotify) {
        if (isNotify) {
            onShowMonthView();
        }
        mWeekPager.setVisibility(HIDE);
        mMonthView.setVisibility(VISIBLE);
    }

    /**
     * 显示周视图
     */
    private void showWeek() {
        onShowWeekView();
        if (mWeekPager != null && mWeekPager.getProvider() != null) {
            mWeekPager.getProvider().notifyDataChanged();
            mWeekPager.setVisibility(VISIBLE);
        }
        mMonthView.setVisibility(INVISIBLE);
    }

    /**
     * 周视图显示事件
     */
    private void onShowWeekView() {
        if (mWeekPager.getVisibility() == VISIBLE) {
            return;
        }
        if (mDelegate != null && mDelegate.mViewChangeListener != null && !isWeekView) {
            mDelegate.mViewChangeListener.onViewChange(false);
        }
    }


    /**
     * 周视图显示事件
     */
    private void onShowMonthView() {
        if (mMonthView.getVisibility() == VISIBLE) {
            return;
        }
        if (mDelegate != null && mDelegate.mViewChangeListener != null && isWeekView) {
            mDelegate.mViewChangeListener.onViewChange(true);
        }
    }

    /**
     * ContentView是否滚动到顶部 如果完全不适合，就复写这个方法
     *
     * @return 是否滚动到顶部
     */
    protected boolean isScrollTop() {
        if (mContentView instanceof CalendarScrollView) {
            return ((CalendarScrollView) mContentView).isScrollToTop();
        }
        if (mContentView instanceof ListContainer)
            return mContentView.getScrollValue(Component.AXIS_Y) == 0;
        return true;
    }


    /**
     * 隐藏内容布局
     */
    final void hideContentView() {
        if (mContentView == null)
            return;
        mContentView.createAnimatorProperty()
                .moveToY(getHeight() - mMonthView.getHeight())
                .setDuration(220)
                .setStateChangedListener(new StateChangedListenerAdapter() {
                    @Override
                    public void onEnd(Animator animator) {
                        mContentView.setVisibility(INVISIBLE);
//                        mContentView.clearAnimation();
                    }
                }).start();
    }

    /**
     * 显示内容布局
     */
    final void showContentView() {
        if (mContentView == null)
            return;
        mContentView.setTranslationY(getHeight() - mMonthView.getHeight());
        mContentView.setVisibility(VISIBLE);
        mContentView.createAnimatorProperty()
                .moveToY(0)
                .setDuration(180)
                .start();
    }


    @SuppressWarnings("unused")
    private int getCalendarViewHeight() {
        return mMonthView.getVisibility() == VISIBLE ? mDelegate.getWeekBarHeight() + mMonthView.getHeight() :
                mDelegate.getWeekBarHeight() + mDelegate.getCalendarItemHeight();
    }

    /**
     * 如果有十分特别的ContentView，可以自定义实现这个接口
     */
    public interface CalendarScrollView {
        /**
         * 是否滚动到顶部
         *
         * @return 是否滚动到顶部
         */
        boolean isScrollToTop();
    }
}
